home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / winterp-1.13 / src-server / wc_RowColumn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-04  |  27.9 KB  |  659 lines

  1. /* -*-C-*-
  2. ********************************************************************************
  3. *
  4. * File:         wc_RowColumn.c
  5. * RCS:          $Header: wc_RowColumn.c,v 1.4 91/03/14 03:14:59 mayer Exp $
  6. * Description:  XM_ROW_COLUMN_WIDGET_CLASS
  7. * Author:       Niels Mayer, HPLabs
  8. * Created:      Sat Oct 28 04:28:02 1989
  9. * Modified:     Thu Oct  3 23:40:39 1991 (Niels Mayer) mayer@hplnpm
  10. * Language:     C
  11. * Package:      N/A
  12. * Status:       X11r5 contrib tape release
  13. *
  14. * WINTERP Copyright 1989, 1990, 1991 Hewlett-Packard Company (by Niels Mayer).
  15. * XLISP version 2.1, Copyright (c) 1989, by David Betz.
  16. *
  17. * Permission to use, copy, modify, distribute, and sell this software and its
  18. * documentation for any purpose is hereby granted without fee, provided that
  19. * the above copyright notice appear in all copies and that both that
  20. * copyright notice and this permission notice appear in supporting
  21. * documentation, and that the name of Hewlett-Packard and David Betz not be
  22. * used in advertising or publicity pertaining to distribution of the software
  23. * without specific, written prior permission.  Hewlett-Packard and David Betz
  24. * make no representations about the suitability of this software for any
  25. * purpose. It is provided "as is" without express or implied warranty.
  26. *
  27. * HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  28. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  29. * IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  30. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  31. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  32. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  33. * PERFORMANCE OF THIS SOFTWARE.
  34. *
  35. * See ./winterp/COPYRIGHT for information on contacting the authors.
  36. * Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  37. * Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  38. *
  39. ********************************************************************************
  40. */
  41. static char rcs_identity[] = "@(#)$Header: wc_RowColumn.c,v 1.4 91/03/14 03:14:59 mayer Exp $";
  42.  
  43. #include <stdio.h>
  44. #include <Xm/Xm.h>
  45. #include <Xm/RowColumn.h>
  46. #include "winterp.h"
  47. #include "user_prefs.h"
  48. #include "xlisp/xlisp.h"
  49. #include "w_funtab.h"
  50.  
  51.  
  52. extern Widget Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(); /* w_classes.c */
  53.  
  54.  
  55. /*****************************************************************************
  56.  * (send XM_ROW_COLUMN_WIDGET_CLASS :new 
  57.  *                           [:managed/:unmanaged]
  58.  *                           [:radio_box/:option_menu/:menu_bar/
  59.  *                            :popup_menu,:pulldown_menu]
  60.  *                           [<name>]
  61.  *                           <parent> 
  62.  *                           [:XMN_<arg1> <val1>]
  63.  *                           [. . .             ]
  64.  *                           [:XMN_<argN> <valN>])
  65.  *
  66.  * The optional keyword submessage :managed will cause a subsequent call
  67.  * to XtManageChild(). If the submessage :unmanaged is present, or no
  68.  * submessage, then XtManageChild() won't be called, and the resulting
  69.  * widget will be returned unmanaged.
  70.  *
  71.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new ...)
  72.  *     -->  XmCreateRowColumn();
  73.  *
  74.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :work_area...)        -- Motif 1.1 only
  75.  *     -->  XmCreateWorkArea();                        -- Motif 1.1 only
  76.  *
  77.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :radio_box ...)
  78.  *     -->  XmCreateRadioBox();
  79.  *
  80.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :simple_radio_box ...)    -- Motif 1.1 only
  81.  *     -->  XmCreateSimpleRadioBox();                    -- Motif 1.1 only
  82.  *
  83.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :option_menu ...)
  84.  *     --> XmCreateOptionMenu();
  85.  *
  86.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :simple_option_menu ...)    -- Motif 1.1 only
  87.  *     --> XmCreateSimpleOptionMenu();                                    -- Motif 1.1 only
  88.  *
  89.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :menu_bar ...)
  90.  *     --> XmCreateMenuBar();
  91.  *
  92.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :simple_menu_bar ...)    -- Motif 1.1 only
  93.  *     --> XmCreateSimpleMenuBar();                    -- Motif 1.1 only
  94.  *
  95.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :popup_menu ...)
  96.  *     --> XmCreatePopupMenu();
  97.  *
  98.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :simple_popup_menu ...)    -- Motif 1.1 only
  99.  *     --> XmCreateSimplePopupMenu();                    -- Motif 1.1 only
  100.  *
  101.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :pulldown_menu ...)
  102.  *     --> XmCreatePulldownMenu();
  103.  *
  104.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :simple_pulldown_menu ...) -- Motif 1.1 only
  105.  *     --> XmCreateSimplePulldownMenu();                    -- Motif 1.1 only
  106.  *
  107.  *     (send XM_ROW_COLUMN_WIDGET_CLASS :new :simple_check_box ...)    -- Motif 1.1 only
  108.  *     --> XmCreateSimpleCheckBox();                    -- Motif 1.1 only
  109.  ****************************************************************************/
  110. static LVAL k_RADIO_BOX, k_OPTION_MENU, k_MENU_BAR, k_POPUP_MENU, k_PULLDOWN_MENU;
  111. #ifdef WINTERP_MOTIF_11
  112. static LVAL k_WORK_AREA, k_SIMPLE_RADIO_BOX, k_SIMPLE_OPTION_MENU, k_SIMPLE_MENU_BAR, k_SIMPLE_POPUP_MENU, k_SIMPLE_PULLDOWN_MENU, k_SIMPLE_CHECK_BOX;
  113. #endif                /* WINTERP_MOTIF_11 */
  114. LVAL Xm_Row_Column_Widget_Class_Method_ISNEW()
  115. {
  116.   extern ArgList Wres_Get_LispArglist(); /* from w_resources.c */
  117.   extern void    Wres_Free_C_Arglist_Data(); /* from w_resources.c */
  118.   extern LVAL k_managed, k_unmanaged;
  119.   LVAL self, o_parent;
  120.   char* name;
  121.   Boolean managed_p;
  122.   LVAL rc_kind;
  123.   Widget widget_id, parent_widget_id;
  124.  
  125.   self = xlgaobject();        /* NOTE: xlobj.c:clnew() returns an OBJECT; if this method
  126.                    returns successfully, it will return a WIDGETOBJ */
  127.   
  128.   /* get optional managed/unmanaged arg */
  129.   if (moreargs() && ((*xlargv == k_managed) || (*xlargv == k_unmanaged)))
  130.     managed_p = (nextarg() == k_managed);
  131.   else
  132.     managed_p = FALSE;        /* by default don't call XtManageChild() */
  133.  
  134.   /* get optional :radio_box/:option_menu... arg */
  135.   if (moreargs() && (   (*xlargv == k_RADIO_BOX)
  136.              || (*xlargv == k_OPTION_MENU)
  137.              || (*xlargv == k_MENU_BAR)
  138.              || (*xlargv == k_POPUP_MENU)
  139.              || (*xlargv == k_PULLDOWN_MENU)
  140. #ifdef WINTERP_MOTIF_11
  141.              || (*xlargv == k_WORK_AREA)
  142.              || (*xlargv == k_SIMPLE_RADIO_BOX)
  143.              || (*xlargv == k_SIMPLE_OPTION_MENU)
  144.              || (*xlargv == k_SIMPLE_MENU_BAR)
  145.              || (*xlargv == k_SIMPLE_POPUP_MENU)
  146.              || (*xlargv == k_SIMPLE_PULLDOWN_MENU)
  147.              || (*xlargv == k_SIMPLE_CHECK_BOX)
  148. #endif                /* WINTERP_MOTIF_11 */
  149.              ))
  150.     rc_kind = nextarg();
  151.   else
  152.     rc_kind = NIL;        /* default is XmCreateRowColumn() */
  153.  
  154.   /* get optional <name> arg */
  155.   if (moreargs() && (stringp(*xlargv)))
  156.     name = (char*) getstring(nextarg());
  157.   else
  158.     name = "";            /* default name */
  159.  
  160.   /* get required <parent> widget-object arg */
  161.   parent_widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&o_parent);
  162.  
  163.   /*
  164.    * Store the widget object <self> in the XmNuserData resource on the
  165.    * widget. This will allow us to retrieve the widget object from Xtoolkit
  166.    * functions returning widget ID's without having to keep around a table
  167.    * of widgetID-->widget-objects.
  168.    */
  169.   ARGLIST_RESET(); ARGLIST_ADD(XmNuserData, (XtArgVal) self); 
  170.  
  171.   if (moreargs()) {        /* if there are more arguments, */
  172.     Cardinal xt_numargs;    /* then we have some extra widget resources to set */
  173.     ArgList xt_arglist = Wres_Get_LispArglist(self, parent_widget_id, ARGLIST(), &xt_numargs);
  174.     if (rc_kind == NIL)
  175.       widget_id = XmCreateRowColumn(parent_widget_id, name, xt_arglist, xt_numargs);
  176.     else if (rc_kind == k_RADIO_BOX)
  177.       widget_id = XmCreateRadioBox(parent_widget_id, name, xt_arglist, xt_numargs);
  178.     else if (rc_kind == k_OPTION_MENU)
  179.       widget_id = XmCreateOptionMenu(parent_widget_id, name, xt_arglist, xt_numargs);
  180.     else if (rc_kind == k_MENU_BAR)
  181.       widget_id = XmCreateMenuBar(parent_widget_id, name, xt_arglist, xt_numargs);
  182.     else if (rc_kind == k_POPUP_MENU)
  183.       widget_id = XmCreatePopupMenu(parent_widget_id, name, xt_arglist, xt_numargs);
  184.     else if (rc_kind == k_PULLDOWN_MENU)
  185.       widget_id = XmCreatePulldownMenu(parent_widget_id, name, xt_arglist, xt_numargs);
  186. #ifdef WINTERP_MOTIF_11
  187.     else if (rc_kind == k_WORK_AREA)
  188.       widget_id = XmCreateWorkArea(parent_widget_id, name, xt_arglist, xt_numargs);
  189.     else if (rc_kind == k_SIMPLE_RADIO_BOX)
  190.       widget_id = XmCreateSimpleRadioBox(parent_widget_id, name, xt_arglist, xt_numargs);
  191.     else if (rc_kind == k_SIMPLE_OPTION_MENU)
  192.       widget_id = XmCreateSimpleOptionMenu(parent_widget_id, name, xt_arglist, xt_numargs);
  193.     else if (rc_kind == k_SIMPLE_MENU_BAR)
  194.       widget_id = XmCreateSimpleMenuBar(parent_widget_id, name, xt_arglist, xt_numargs);
  195.     else if (rc_kind == k_SIMPLE_POPUP_MENU)
  196.       widget_id = XmCreateSimplePopupMenu(parent_widget_id, name, xt_arglist, xt_numargs);
  197.     else if (rc_kind == k_SIMPLE_PULLDOWN_MENU)
  198.       widget_id = XmCreateSimplePulldownMenu(parent_widget_id, name, xt_arglist, xt_numargs);
  199.     else if (rc_kind == k_SIMPLE_CHECK_BOX)
  200.       widget_id = XmCreateSimpleCheckBox(parent_widget_id, name, xt_arglist, xt_numargs);
  201. #endif                /* WINTERP_MOTIF_11 */
  202.     else
  203.       xlfatal("Bug in Xm_Row_Column_Widget_Class_Method_ISNEW()");
  204.     Wres_Free_C_Arglist_Data();
  205.   }
  206.   else 
  207.     if (rc_kind == NIL)
  208.       widget_id = XmCreateRowColumn(parent_widget_id, name, ARGLIST());
  209.     else if (rc_kind == k_RADIO_BOX)
  210.       widget_id = XmCreateRadioBox(parent_widget_id, name, ARGLIST());
  211.     else if (rc_kind == k_OPTION_MENU)
  212.       widget_id = XmCreateOptionMenu(parent_widget_id, name, ARGLIST());
  213.     else if (rc_kind == k_MENU_BAR)
  214.       widget_id = XmCreateMenuBar(parent_widget_id, name, ARGLIST());
  215.     else if (rc_kind == k_POPUP_MENU)
  216.       widget_id = XmCreatePopupMenu(parent_widget_id, name, ARGLIST());
  217.     else if (rc_kind == k_PULLDOWN_MENU)
  218.       widget_id = XmCreatePulldownMenu(parent_widget_id, name, ARGLIST());
  219. #ifdef WINTERP_MOTIF_11
  220.     else if (rc_kind == k_WORK_AREA)
  221.       widget_id = XmCreateWorkArea(parent_widget_id, name, ARGLIST());
  222.     else if (rc_kind == k_SIMPLE_RADIO_BOX)
  223.       widget_id = XmCreateSimpleRadioBox(parent_widget_id, name, ARGLIST());
  224.     else if (rc_kind == k_SIMPLE_OPTION_MENU)
  225.       widget_id = XmCreateSimpleOptionMenu(parent_widget_id, name, ARGLIST());
  226.     else if (rc_kind == k_SIMPLE_MENU_BAR)
  227.       widget_id = XmCreateSimpleMenuBar(parent_widget_id, name, ARGLIST());
  228.     else if (rc_kind == k_SIMPLE_POPUP_MENU)
  229.       widget_id = XmCreateSimplePopupMenu(parent_widget_id, name, ARGLIST());
  230.     else if (rc_kind == k_SIMPLE_PULLDOWN_MENU)
  231.       widget_id = XmCreateSimplePulldownMenu(parent_widget_id, name, ARGLIST());
  232.     else if (rc_kind == k_SIMPLE_CHECK_BOX)
  233.       widget_id = XmCreateSimpleCheckBox(parent_widget_id, name, ARGLIST());
  234. #endif                /* WINTERP_MOTIF_11 */
  235.     else
  236.       xlfatal("Bug in Xm_Row_Column_Widget_Class_Method_ISNEW()");
  237.  
  238.   Wcls_Initialize_WIDGETOBJ(self, widget_id);
  239.   
  240.   if (managed_p)
  241.     XtManageChild(widget_id);
  242.   
  243. #ifdef DEBUG_WINTERP_1
  244.   Wcls_Print_WidgetObj_Info(self);
  245. #endif
  246.   return (self);
  247. }
  248.  
  249.  
  250. /******************************************************************************
  251.  * typedef struct
  252.  * {
  253.  *     int     reason;
  254.  *     XEvent  *event;
  255.  *     Widget  widget;
  256.  *     char    *data;
  257.  *     char    *callbackstruct;
  258.  * } XmRowColumnCallbackStruct;
  259.  *
  260.  * Note: if rowcol widget has an XmNentryCallback set, then any 
  261.  * activate action on any of it's entries will produce a callback
  262.  * on the rowcol widget with
  263.  *    cb.reason==XmCR_ACTIVATE,
  264.  *    cb.event==cb.callbackstruct->event
  265.  *    cb.widget==<entrywidget>
  266.  *    cb.data==<entrywidget's client-data if a activate callback was spec'd for entry and it had client-data> 
  267.  *    cb.callbackstruct==<entrywidget's call-data> (XmAnyCallbackStruct/XmToggleButtonCallbackStruct)
  268.  *
  269.  * The weird part here is the cb.callbackstruct slot -- we don't know the class
  270.  * of the entrywidget, so we can't know what kind of callbackstruct it got.
  271.  * We can only be guaranteed that the activated-entry-widget's .reason 
  272.  * fields are valid. If we have a toggle button, then we may want to 
  273.  * access the .set slot of the XmToggleButtonCallbackStruct. (??)
  274.  ******************************************************************************/
  275. static LVAL s_CALLBACK_ENTRY_WIDGET, s_CALLBACK_ENTRY_REASON, s_CALLBACK_ENTRY_SET, s_CALLBACK_ENTRY_DATA;
  276. #ifdef WINTERP_MOTIF_11
  277. static LVAL s_CALLBACK_ENTRY_CLICK_COUNT;
  278. #endif                /* WINTERP_MOTIF_11 */
  279.  
  280. static void Lexical_Bindings_For_XmRowColumnCallbackStruct(bindings_list, lexical_env, cd, o_widget)
  281.      LVAL bindings_list;    /* a list of symbols to which values from XmRowColumnCallbackStruct are bound */
  282.      LVAL lexical_env;        
  283.      XmRowColumnCallbackStruct* cd;
  284.      LVAL o_widget;        /* XLTYPE_WIDGETOBJ */
  285. {
  286.   extern LVAL s_CALLBACK_WIDGET, s_CALLBACK_REASON, s_CALLBACK_XEVENT; /* w_callbacks.c */
  287.   extern LVAL Wcb_Get_Callback_Reason_Symbol();    /* w_callbacks.c */
  288.   register LVAL s_bindname;
  289.   extern LVAL true;
  290.   extern LVAL Wcls_WidgetID_To_WIDGETOBJ();
  291.  
  292.   for ( ; consp(bindings_list); bindings_list = cdr(bindings_list)) {
  293.  
  294.     s_bindname = car(bindings_list);
  295.  
  296.     if (s_bindname == s_CALLBACK_WIDGET) {
  297.       xlpbind(s_bindname, o_widget, lexical_env);
  298.     }
  299.     else if (s_bindname == s_CALLBACK_REASON) {
  300.       xlpbind(s_bindname, Wcb_Get_Callback_Reason_Symbol(cd->reason), lexical_env);
  301.     }
  302.     else if (s_bindname == s_CALLBACK_XEVENT) {
  303.       xlpbind(s_bindname, (cd->event) ? cv_xevent(cd->event) : NIL, lexical_env);
  304.     }
  305.     else if (s_bindname == s_CALLBACK_ENTRY_WIDGET) {
  306.       xlpbind(s_bindname, Wcls_WidgetID_To_WIDGETOBJ(cd->widget), lexical_env);
  307.     }
  308.     else if (s_bindname == s_CALLBACK_ENTRY_REASON) {
  309.       xlpbind(s_bindname, (cd->callbackstruct) ? Wcb_Get_Callback_Reason_Symbol(((XmToggleButtonCallbackStruct*) cd->callbackstruct)->reason) : NIL, lexical_env);
  310.     }
  311.     else if (s_bindname == s_CALLBACK_ENTRY_SET) { /* this'll give meaningless results if entry isn't a togglebutton  */
  312.       xlpbind(s_bindname, (cd->callbackstruct) ? ((((XmToggleButtonCallbackStruct*) cd->callbackstruct)->set) ? true : NIL) : NIL, lexical_env);
  313.     }
  314. #ifdef WINTERP_MOTIF_11
  315.     else if (s_bindname == s_CALLBACK_ENTRY_CLICK_COUNT) { /* this'll give meaningless results if entry isn't a pushbutton, drawnbutton, arrowbutton  */
  316.       xlpbind(s_bindname, (cd->callbackstruct) ? cvfixnum((FIXTYPE) ((XmPushButtonCallbackStruct*) cd->callbackstruct)->click_count) : NIL, lexical_env);
  317.     }
  318. #endif                /* WINTERP_MOTIF_11 */
  319.     /* ----- WARNING: Using this could cause coredump!! -- this should dereference to the CALLBACKOBJ set for the entry, else NIL ---- */
  320.     else if (s_bindname == s_CALLBACK_ENTRY_DATA) { 
  321.       xlpbind(s_bindname, (LVAL) cd->data, lexical_env);
  322.     }
  323.     /* ------------------------------------------------------------------------------------------------------------------------------- */
  324.     else {
  325.       extern char temptext[];    /* from winterp.c */
  326.       sprintf(temptext,
  327. #ifdef WINTERP_MOTIF_11
  328.           "Unknown binding name in XmRowColumnCallbackStruct callback evaluator. Valid symbols are [%s %s %s %s %s %s %s %s].",
  329. #else                /* Motif 1.0 */
  330.           "Unknown binding name in XmRowColumnCallbackStruct callback evaluator. Valid symbols are [%s %s %s %s %s %s %s].",
  331. #endif                /* WINTERP_MOTIF_11 */
  332.           (char*) getstring(getpname(s_CALLBACK_WIDGET)),
  333.           (char*) getstring(getpname(s_CALLBACK_REASON)),
  334.           (char*) getstring(getpname(s_CALLBACK_XEVENT)),
  335.           (char*) getstring(getpname(s_CALLBACK_ENTRY_WIDGET)),
  336.           (char*) getstring(getpname(s_CALLBACK_ENTRY_REASON)),
  337.           (char*) getstring(getpname(s_CALLBACK_ENTRY_SET)),
  338. #ifdef WINTERP_MOTIF_11
  339.           (char*) getstring(getpname(s_CALLBACK_ENTRY_CLICK_COUNT)),
  340. #endif                /* WINTERP_MOTIF_11 */
  341.           (char*) getstring(getpname(s_CALLBACK_ENTRY_DATA)));
  342.       xlerror(temptext, s_bindname);
  343.     }
  344.   }
  345. }
  346.  
  347.  
  348. /******************************************************************************
  349.  * This is called indirectly via XtAddCallback() for callbacks returning
  350.  * an XmRowColumnCallbackStruct as call_data.
  351.  ******************************************************************************/
  352. static void XmRowColumnCallbackStruct_Callbackproc(widget, client_data, call_data)
  353.      Widget    widget;
  354.      XtPointer client_data;
  355.      XtPointer call_data;
  356. {
  357.   extern void Wcb_Meta_Callbackproc(); /* w_callbacks.c */
  358.  
  359.   Wcb_Meta_Callbackproc(client_data, call_data,
  360.             Lexical_Bindings_For_XmRowColumnCallbackStruct,
  361.             NULL);
  362. }
  363.  
  364.  
  365. /******************************************************************************
  366.  * Same as WIDGET_CLASS's :add_callback method except that this understands
  367.  * how to get values from the XmRowColumnCallbackStruct.
  368.  * Specifying one or more of the following symbols in the callback bindings 
  369.  * list will bind that symbol's value in the lexical environment of the callback:
  370.  * CALLBACK_WIDGET
  371.  * CALLBACK_REASON
  372.  * CALLBACK_XEVENT
  373.  * CALLBACK_ENTRY_WIDGET
  374.  * CALLBACK_ENTRY_REASON
  375.  * CALLBACK_ENTRY_SET
  376.  * CALLBACK_ENTRY_DATA
  377.  * CALLBACK_ENTRY_CLICK_COUNT -- new resource for Motif 1.1
  378.  ******************************************************************************/
  379. LVAL Xm_Row_Column_Widget_Class_Method_ADD_CALLBACK()
  380. {
  381.   extern LVAL Wcb_Meta_Method_Add_Callback(); /* w_callbacks.c */
  382.  
  383.   return (Wcb_Meta_Method_Add_Callback(XmRowColumnCallbackStruct_Callbackproc, FALSE));
  384. }
  385.  
  386.  
  387. /******************************************************************************
  388.  * Same as WIDGET_CLASS's :set_callback method except that this understands
  389.  * how to get values from the XmRowColumnCallbackStruct.
  390.  * Specifying one or more of the following symbols in the callback bindings 
  391.  * list will bind that symbol's value in the lexical environment of the callback:
  392.  * CALLBACK_WIDGET
  393.  * CALLBACK_REASON
  394.  * CALLBACK_XEVENT
  395.  * CALLBACK_ENTRY_WIDGET
  396.  * CALLBACK_ENTRY_REASON
  397.  * CALLBACK_ENTRY_SET
  398.  * CALLBACK_ENTRY_DATA
  399.  * CALLBACK_ENTRY_CLICK_COUNT -- new resource for Motif 1.1
  400.  ******************************************************************************/
  401. LVAL Xm_Row_Column_Widget_Class_Method_SET_CALLBACK()
  402. {
  403.   extern LVAL Wcb_Meta_Method_Add_Callback(); /* w_callbacks.c */
  404.  
  405.   return (Wcb_Meta_Method_Add_Callback(XmRowColumnCallbackStruct_Callbackproc, TRUE));
  406. }
  407.  
  408.  
  409. /******************************************************************************
  410.  * (send <popup_menu> :MENU_POSITION <event>)
  411.  *      ==> returns <popup_menu>
  412.  * This method will position a popup menupane at the position specified by
  413.  * event->x_root, event->y_root, where <event> is an XEvent. This
  414.  * method should only be called on a row_column widget that was created via
  415.  * (send XM_ROW_COLUMN_WIDGET_CLASS :new :popup_menu ...).
  416.  *
  417.  * Possible design change: should I make a POPUP_MENU_WIDGET_CLASS that
  418.  * has this as one of it's methods, and don't provide this method on
  419.  * other rowcolumn widgets?
  420.  *
  421.  * void XmMenuPosition (p, event)
  422.  *     Widget  p;
  423.  *     XButtonPressedEvent *event;
  424.  ******************************************************************************/
  425. LVAL Xm_Row_Column_Widget_Class_Method_MENU_POSITION()
  426. {
  427.   LVAL self;
  428.   Widget widget_id;
  429.   XEvent *event;
  430.  
  431.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  432.   event = get_xevent(xlga_xevent());
  433.   xllastarg();
  434.   
  435.   XmMenuPosition(widget_id, event);
  436.   
  437.   return (self);
  438. }
  439.  
  440.  
  441. /******************************************************************************
  442.  * (send <option_menu> :OPTION_LABEL_GADGET)
  443.  *      ==> this method returns the WIDGETOBJ corresponding to the label
  444.  *          gadget created in an <option_menu> instance. An <option_menu>
  445.  *          rowcolumn instance can be created by doing
  446.  *          (send XM_ROW_COLUMN_WIDGET_CLASS :new :option_menu ...)
  447.  *
  448.  * Widget XmOptionLabelGadget (m)
  449.  *     Widget   m;
  450.  ******************************************************************************/
  451. LVAL Xm_Row_Column_Widget_Class_Method_OPTION_LABEL_GADGET()
  452. {
  453.   extern LVAL Wcls_WidgetID_To_WIDGETOBJ();
  454.   LVAL self;
  455.   Widget widget_id;
  456.  
  457.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  458.   xllastarg();
  459.   
  460.   return (Wcls_WidgetID_To_WIDGETOBJ(XmOptionLabelGadget(widget_id)));
  461. }
  462.  
  463.  
  464. /******************************************************************************
  465.  * (send <option_menu> :OPTION_BUTTON_GADGET)
  466.  *      ==> this method returns the WIDGETOBJ corresponding to the cascade
  467.  *          button gadget created in an <option_menu> instance. An
  468.  *          <option_menu> rowcolumn instance can be created by doing
  469.  *          (send XM_ROW_COLUMN_WIDGET_CLASS :new :option_menu ...)
  470.  *
  471.  * Widget XmOptionButtonGadget (m)
  472.  *     Widget   m;
  473.  ******************************************************************************/
  474. LVAL Xm_Row_Column_Widget_Class_Method_OPTION_BUTTON_GADGET()
  475. {
  476.   extern LVAL Wcls_WidgetID_To_WIDGETOBJ();
  477.   LVAL self;
  478.   Widget widget_id;
  479.  
  480.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  481.   xllastarg();
  482.  
  483.   return (Wcls_WidgetID_To_WIDGETOBJ(XmOptionButtonGadget(widget_id)));
  484. }
  485.  
  486.  
  487. #ifdef WINTERP_MOTIF_11
  488. /******************************************************************************
  489.  * (send <menu> :GET_POSTED_FROM_WIDGET)
  490.  *      ==> this method returns the WIDGETOBJ corresponding to the the widget
  491.  * from which the menu was posted. in a popup, it is the widget which initiated
  492.  * the post. If it is in a pulldown from a menubar or option menu, then the
  493.  * returned widget is the menubar or option menu.
  494.  *
  495.  * ----------------------------------------------------------------------------
  496.  *  Widget XmGetPostedFromWidget (Widget menu);
  497.  ******************************************************************************/
  498. LVAL Xm_Row_Column_Widget_Class_Method_GET_POSTED_FROM_WIDGET()
  499. {
  500.   extern LVAL Wcls_WidgetID_To_WIDGETOBJ();
  501.   LVAL self;
  502.   Widget widget_id;
  503.  
  504.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  505.   xllastarg();
  506.   
  507.   return (Wcls_WidgetID_To_WIDGETOBJ(XmGetPostedFromWidget(widget_id)));
  508. }
  509. #endif                /* WINTERP_MOTIF_11 */
  510.  
  511.  
  512. #ifdef WINTERP_MOTIF_11
  513. /*
  514.  * <limits.h> defines machine dependent limits on sizes of numbers, if your
  515.  * machine doesn't have this, then your compiler doesn't conform to standards
  516.  * XPG2, XPG3, POSIX.1, FIPS 151-1 and you should complain to the manufacturer.
  517.  * 
  518.  * If for some reason your system isn't standards-conforming, you may work
  519.  * around this problem by using the following definitions (assuming 32 bit machine):
  520.  * 
  521.  * #define LONG_MIN (-2147483647 - 1)
  522.  */
  523. #include <limits.h>
  524. /******************************************************************************
  525.  * (send <rowcolwidget> :GET_SUB_MENU_WIDGET)
  526.  *      ==> this method returns the WIDGETOBJ corresponding to the the widget
  527.  * returned by resource XmNsubMenuId.
  528.  *
  529.  * Due to some weird 1.1 bug, (perhaps in motif) doing
  530.  * (send <rowcolwidget> :get_values :xmn_sub_menu_id nil) returns
  531.  * <rowcolwidget>. This seems to be failing in the same way that :PARENT
  532.  * is failing on scrolled text and list widgets. See comments in 
  533.  * wc_Text.c:Xm_Text_Widget_Class_Method_PARENT() and
  534.  * wc_List.c:Xm_List_Widget_Class_Method_PARENT()
  535.  * for details.
  536.  * ----------------------------------------------------------------------------
  537.  ******************************************************************************/
  538. LVAL Xm_Row_Column_Widget_Class_Method_GET_SUB_MENU_WIDGET()
  539. {
  540.   extern LVAL Wcls_WidgetClassID_To_WIDGETCLASSOBJ(); /* w_classes.c */
  541.   extern LVAL Wcls_WidgetID_To_WIDGETOBJ(); /* w_classes.c */
  542.  
  543.   LVAL self, lval_submenuid;
  544.   Widget widget_id, submenu_id;
  545.   XtPointer widget_data = (XtPointer) LONG_MIN;
  546.  
  547.   widget_id = Wcls_Get_WIDGETOBJ_Argument_Returning_Validated_WidgetID(&self);
  548.   xllastarg();
  549.  
  550.   ARGLIST_RESET(); ARGLIST_ADD(XmNsubMenuId, &widget_data);
  551.   XtGetValues(widget_id, ARGLIST());
  552.   if (widget_data == (XtPointer) LONG_MIN) /* make sure that XmNsubMenuId resource actually exists on the widget in question. */
  553.     xlfail("Internal error in Xm_Row_Column_Widget_Class_Method_GET_SUB_MENU_WIDET() -- couldn't retrieve XmNsubMenuId resource from widget. Motif bug?");
  554.   if (widget_data == NULL)
  555.     return (NIL);
  556.  
  557.   submenu_id = (Widget) widget_data;
  558.  
  559.   lval_submenuid = Wcls_WidgetID_To_WIDGETOBJ(submenu_id);
  560.   
  561.   if (lval_submenuid != self)
  562.     return (lval_submenuid);
  563.   else {            /* handle motif 1.1 fuckup */
  564.     LVAL o_widgetclass;
  565.     if (o_widgetclass = Wcls_WidgetClassID_To_WIDGETCLASSOBJ(XtClass(submenu_id))) /* returns NIL on failure */
  566.       /* (2): Create a new WIDGETOBJ of the appropriate class. */
  567.       lval_submenuid = newobject(o_widgetclass, WIDGETOBJ_SIZE);
  568.     else {            /* fail gracefully (i think). */
  569.       extern LVAL o_WIDGET_CLASS; /* from wc_WIDGET.c */
  570.       errputstr("Warning -- In Wcls_WidgetID_To_WIDGETOBJ() couldn't find a valid\n");
  571.       errputstr("           widgetclass object inside widget classrecord. Creating\n");
  572.       errputstr("           a \"generic\" WIDGETOBJ of class WIDGET_CLASS.\n");
  573.       lval_submenuid = newobject(o_WIDGET_CLASS, WIDGETOBJ_SIZE);
  574.     }
  575.     Wcls_Initialize_WIDGETOBJ(lval_submenuid, submenu_id);
  576.     
  577.     /* Store the pointer to the new widgetobj in the widget's XmNuserData resource. */
  578.     ARGLIST_RESET(); ARGLIST_ADD(XmNuserData, (XtArgVal) lval_submenuid);
  579.     XtSetValues(submenu_id, ARGLIST());  
  580.     return (lval_submenuid);
  581.   }
  582. }
  583. #endif                /* WINTERP_MOTIF_11 */
  584.  
  585.  
  586. /******************************************************************************
  587.  *
  588.  ******************************************************************************/
  589. Wc_RowColumn_Init()
  590. {
  591.   LVAL o_XM_ROW_COLUMN_WIDGET_CLASS;
  592.   extern LVAL Wcls_Create_Subclass_Of_WIDGET_CLASS(); /* w_classes.c */
  593.   extern      xladdmsg();    /* from xlobj.c */
  594.  
  595. #ifdef WINTERP_MOTIF_11
  596.   k_WORK_AREA        = xlenter(":WORK_AREA");
  597.   k_SIMPLE_RADIO_BOX    = xlenter(":SIMPLE_RADIO_BOX");
  598.   k_SIMPLE_OPTION_MENU    = xlenter(":SIMPLE_OPTION_MENU");
  599.   k_SIMPLE_MENU_BAR    = xlenter(":SIMPLE_MENU_BAR");
  600.   k_SIMPLE_POPUP_MENU    = xlenter(":SIMPLE_POPUP_MENU");
  601.   k_SIMPLE_PULLDOWN_MENU = xlenter(":SIMPLE_PULLDOWN_MENU");
  602.   k_SIMPLE_CHECK_BOX    = xlenter(":SIMPLE_CHECK_BOX");
  603. #endif                /* WINTERP_MOTIF_11 */
  604.   k_RADIO_BOX          = xlenter(":RADIO_BOX");
  605.   k_OPTION_MENU        = xlenter(":OPTION_MENU");
  606.   k_MENU_BAR           = xlenter(":MENU_BAR");
  607.   k_POPUP_MENU         = xlenter(":POPUP_MENU");
  608.   k_PULLDOWN_MENU      = xlenter(":PULLDOWN_MENU");
  609.  
  610.   s_CALLBACK_ENTRY_WIDGET = xlenter("CALLBACK_ENTRY_WIDGET");
  611.   s_CALLBACK_ENTRY_REASON = xlenter("CALLBACK_ENTRY_REASON");
  612.   s_CALLBACK_ENTRY_SET    = xlenter("CALLBACK_ENTRY_SET");
  613.   s_CALLBACK_ENTRY_DATA   = xlenter("CALLBACK_ENTRY_DATA");
  614. #ifdef WINTERP_MOTIF_11
  615.   s_CALLBACK_ENTRY_CLICK_COUNT = xlenter("CALLBACK_ENTRY_CLICK_COUNT");
  616. #endif                /* WINTERP_MOTIF_11 */
  617.  
  618.   o_XM_ROW_COLUMN_WIDGET_CLASS =
  619.     Wcls_Create_Subclass_Of_WIDGET_CLASS("XM_ROW_COLUMN_WIDGET_CLASS",
  620.                      xmRowColumnWidgetClass);
  621.  
  622.   /*
  623.    * a special :isnew method on this class allows for the creation of this
  624.    * widget inside a popup shell if one of the following submessage keywords
  625.    * are given: 
  626.    * :RADIO_BOX, :OPTION_MENU, :MENU_BAR, :POPUP_MENU, :PULLDOWN_MENU, :WORK_AREA
  627.    * :SIMPLE_RADIO_BOX, :SIMPLE_OPTION_MENU, :SIMPLE_MENU_BAR, :SIMPLE_POPUP_MENU,
  628.    * :SIMPLE_PULLDOWN_MENU, :SIMPLE_CHECK_BOX
  629.    */
  630.   xladdmsg(o_XM_ROW_COLUMN_WIDGET_CLASS, ":ISNEW", 
  631.        FTAB_Xm_Row_Column_Widget_Class_Method_ISNEW);
  632.  
  633.   xladdmsg(o_XM_ROW_COLUMN_WIDGET_CLASS, ":ADD_CALLBACK",
  634.            FTAB_Xm_Row_Column_Widget_Class_Method_ADD_CALLBACK);
  635.  
  636.   xladdmsg(o_XM_ROW_COLUMN_WIDGET_CLASS, ":SET_CALLBACK",
  637.            FTAB_Xm_Row_Column_Widget_Class_Method_SET_CALLBACK);
  638.  
  639.   xladdmsg(o_XM_ROW_COLUMN_WIDGET_CLASS, ":MENU_POSITION",
  640.            FTAB_Xm_Row_Column_Widget_Class_Method_MENU_POSITION);
  641.  
  642.   xladdmsg(o_XM_ROW_COLUMN_WIDGET_CLASS, ":OPTION_LABEL_GADGET",
  643.            FTAB_Xm_Row_Column_Widget_Class_Method_OPTION_LABEL_GADGET);
  644.  
  645.   xladdmsg(o_XM_ROW_COLUMN_WIDGET_CLASS, ":OPTION_BUTTON_GADGET",
  646.            FTAB_Xm_Row_Column_Widget_Class_Method_OPTION_BUTTON_GADGET);
  647.  
  648. #ifdef WINTERP_MOTIF_11
  649.   xladdmsg(o_XM_ROW_COLUMN_WIDGET_CLASS, ":GET_POSTED_FROM_WIDGET",
  650.            FTAB_Xm_Row_Column_Widget_Class_Method_GET_POSTED_FROM_WIDGET);
  651. #endif                /* WINTERP_MOTIF_11 */
  652.  
  653. #ifdef WINTERP_MOTIF_11
  654.   xladdmsg(o_XM_ROW_COLUMN_WIDGET_CLASS, ":GET_SUB_MENU_WIDGET",
  655.            FTAB_Xm_Row_Column_Widget_Class_Method_GET_SUB_MENU_WIDGET);
  656. #endif                /* WINTERP_MOTIF_11 */
  657. }
  658.